<script setup lang="ts">
import { watchDebounced } from '@vueuse/core'
import * as echarts from 'echarts'
import { NNumberAnimation } from 'naive-ui'
import { onMounted, watch, ref, onUnmounted } from 'vue'

import { ScrollContainer } from '@/components'
import { toRefsPreferencesStore } from '@/stores'
import twc from '@/utils/tailwindColor'

import type { ECharts } from 'echarts'

defineOptions({
  name: 'DashboardWorkbench',
})

const { sidebarMenu, navigationMode, themeColor, isDark } = toRefsPreferencesStore()

const taskStats = ref<TaskStatItem[]>(generateTaskStats())
const recentTasks = ref(generateRecentTasks())
const upcomingEvents = ref(generateUpcomingEvents())
const activityFeed = ref(generateActivityFeed())

const taskProgressChart = ref<HTMLDivElement | null>(null)
let taskProgressChartInstance: ECharts | null = null
let taskProgressChartResizeHandler: (() => void) | null = null

interface TaskStatItem {
  title: string
  value: number
  iconClass: string
  iconBgClass: string
  color: string
}

function generateTaskStats(): TaskStatItem[] {
  return [
    {
      title: '待处理',
      value: Math.floor(15 + Math.random() * 20),
      iconClass: 'iconify ph--clock-bold text-yellow-50 dark:text-yellow-150',
      iconBgClass:
        'text-yellow-500/5 bg-yellow-400 ring-4 ring-yellow-200 dark:bg-yellow-650 dark:ring-yellow-500/30 transition-all',
      color: twc.yellow[500],
    },
    {
      title: '进行中',
      value: Math.floor(20 + Math.random() * 25),
      iconClass: 'iconify ph--hourglass-bold text-blue-50 dark:text-blue-150',
      iconBgClass:
        'text-blue-500/5 bg-blue-400 ring-4 ring-blue-200 dark:bg-blue-650 dark:ring-blue-500/30 transition-all',
      color: twc.blue[500],
    },
    {
      title: '已完成',
      value: Math.floor(80 + Math.random() * 40),
      iconClass: 'iconify ph--check-circle-bold text-green-50 dark:text-green-150',
      iconBgClass:
        'text-green-500/5 bg-green-400 ring-4 ring-green-200 dark:bg-green-650 dark:ring-green-500/30 transition-all',
      color: twc.green[500],
    },
    {
      title: '已逾期',
      value: Math.floor(5 + Math.random() * 10),
      iconClass: 'iconify ph--x-circle-bold text-red-50 dark:text-red-150',
      iconBgClass:
        'text-red-500/5 bg-red-400 ring-4 ring-red-200 dark:bg-red-650 dark:ring-red-500/30 transition-all',
      color: twc.red[500],
    },
  ] as const
}

function generateRecentTasks() {
  const statuses = ['pending', 'in-progress', 'completed', 'overdue']
  const priorities = ['low', 'medium', 'high', 'urgent']
  const taskTitles = [
    '完成项目需求文档',
    '设计新功能界面',
    '修复登录页面bug',
    '优化数据库查询',
    '更新用户手册',
    '参加团队会议',
    '部署新版本',
    '编写单元测试',
  ]

  return Array.from({ length: 8 }, (_, i) => ({
    id: i + 1,
    title: taskTitles[Math.floor(Math.random() * taskTitles.length)],
    status: statuses[Math.floor(Math.random() * statuses.length)] as
      | 'pending'
      | 'in-progress'
      | 'completed'
      | 'overdue',
    priority: priorities[Math.floor(Math.random() * priorities.length)] as
      | 'low'
      | 'medium'
      | 'high'
      | 'urgent',
    assignee: `用户${i + 1}`,
    dueDate: new Date(Date.now() + Math.random() * 7 * 24 * 60 * 60 * 1000).toLocaleDateString(
      'zh-CN',
    ),
  }))
}

function generateUpcomingEvents() {
  const eventTitles = [
    '周例会',
    '产品评审会',
    '技术分享会',
    '客户演示',
    '代码审查',
    ' sprint 计划会',
  ]

  return Array.from({ length: 4 }, (_, i) => ({
    id: i + 1,
    title: eventTitles[Math.floor(Math.random() * eventTitles.length)],
    time: `${Math.floor(9 + Math.random() * 8)}:${String(Math.floor(Math.random() * 60)).padStart(2, '0')}`,
    location: `会议室 ${i + 1}`,
  }))
}

function generateActivityFeed() {
  const activities = [
    '创建了新任务',
    '完成了项目文档',
    '评论了需求变更',
    '更新了系统设置',
    '部署了新版本',
    '修复了关键bug',
  ]

  return Array.from({ length: 6 }, (_, i) => ({
    id: i + 1,
    user: `用户${Math.floor(Math.random() * 10) + 1}`,
    activity: activities[Math.floor(Math.random() * activities.length)],
    time: `${Math.floor(Math.random() * 24)}小时前`,
    iconClass: 'iconify ph--activity',
  }))
}

const createTooltipConfig = (formatter?: any) => ({
  trigger: 'axis',
  backgroundColor: isDark.value ? twc.neutral[750] : '#fff',
  borderWidth: 1,
  borderColor: isDark.value ? twc.neutral[700] : twc.neutral[150],
  padding: 8,
  extraCssText: 'box-shadow: none;',
  textStyle: {
    color: isDark.value ? twc.neutral[400] : twc.neutral[600],
    fontSize: 12,
  },
  axisPointer: {
    type: 'none',
  },
  ...(formatter && { formatter }),
})

function initTaskProgressChart() {
  if (!taskProgressChart.value) return

  const chart = echarts.init(taskProgressChart.value)

  const taskStatsData = taskStats.value
  const taskData = [
    {
      name: '待处理',
      value: (taskStatsData[0] as TaskStatItem).value,
      color: (taskStatsData[0] as TaskStatItem).color,
    },
    {
      name: '进行中',
      value: (taskStatsData[1] as TaskStatItem).value,
      color: (taskStatsData[1] as TaskStatItem).color,
    },
    {
      name: '已完成',
      value: (taskStatsData[2] as TaskStatItem).value,
      color: (taskStatsData[2] as TaskStatItem).color,
    },
    {
      name: '已逾期',
      value: (taskStatsData[3] as TaskStatItem).value,
      color: (taskStatsData[3] as TaskStatItem).color,
    },
  ]

  const option = {
    title: {
      text: '任务进度概览',
      left: 0,
      top: 0,
      textStyle: {
        fontSize: 15,
        color: isDark.value ? twc.neutral[400] : twc.neutral[600],
        fontWeight: 'normal',
      },
    },
    tooltip: createTooltipConfig((params: any) => {
      return `<div>${params[0].name}: ${params[0].value} 项</div>`
    }),
    grid: {
      left: 0,
      right: 0,
      top: 40,
      bottom: 0,
      containLabel: true,
    },
    series: [
      {
        name: '任务状态',
        type: 'pie',
        radius: ['50%', '70%'],
        center: ['50%', '55%'],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 8,
          borderColor: isDark.value ? twc.neutral[800] : '#fff',
          borderWidth: 2,
        },
        label: {
          show: false,
          position: 'center',
        },
        emphasis: {
          label: {
            show: true,
            fontSize: '20',
            fontWeight: 'bold',
            formatter: '{b}: {c} 项',
            color: isDark.value ? twc.neutral[400] : twc.neutral[600],
          },
        },
        labelLine: {
          show: false,
        },
        data: taskData,
      },
    ],
    animationDuration: 1000,
    animationEasing: 'cubicOut' as const,
  }

  chart.setOption(option)

  taskProgressChartInstance = chart
  taskProgressChartResizeHandler = () => chart.resize()
  window.addEventListener('resize', taskProgressChartResizeHandler, { passive: true })
}

function resizeAllCharts() {
  if (taskProgressChartInstance) taskProgressChartInstance.resize()
}

watchDebounced([() => sidebarMenu.value, () => navigationMode.value], resizeAllCharts, {
  debounce: 300,
  deep: true,
})

watch([isDark, themeColor], () => {
  // 销毁并重新初始化图表以适应主题变化
  if (taskProgressChartInstance) {
    if (taskProgressChartResizeHandler) {
      window.removeEventListener('resize', taskProgressChartResizeHandler)
      taskProgressChartResizeHandler = null
    }
    taskProgressChartInstance.dispose()
    taskProgressChartInstance = null
  }

  initTaskProgressChart()
})

onMounted(() => {
  initTaskProgressChart()
})

onUnmounted(() => {
  if (taskProgressChartInstance) {
    if (taskProgressChartResizeHandler) {
      window.removeEventListener('resize', taskProgressChartResizeHandler)
      taskProgressChartResizeHandler = null
    }
    taskProgressChartInstance.dispose()
    taskProgressChartInstance = null
  }
})

const getStatusBadgeClass = (status: string) => {
  switch (status) {
    case 'pending':
      return 'bg-yellow-100 text-yellow-600 dark:bg-yellow-500/20 dark:text-yellow-400'
    case 'in-progress':
      return 'bg-blue-100 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400'
    case 'completed':
      return 'bg-green-100 text-green-600 dark:bg-green-500/20 dark:text-green-400'
    case 'overdue':
      return 'bg-red-100 text-red-600 dark:bg-red-500/20 dark:text-red-400'
    default:
      return 'bg-neutral-100 text-neutral-600 dark:bg-neutral-700 dark:text-neutral-400'
  }
}

const getPriorityBadgeClass = (priority: string) => {
  switch (priority) {
    case 'low':
      return 'bg-green-100 text-green-600 dark:bg-green-500/20 dark:text-green-400'
    case 'medium':
      return 'bg-blue-100 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400'
    case 'high':
      return 'bg-orange-100 text-orange-600 dark:bg-orange-500/20 dark:text-orange-400'
    case 'urgent':
      return 'bg-red-100 text-red-600 dark:bg-red-500/20 dark:text-red-400'
    default:
      return 'bg-neutral-100 text-neutral-600 dark:bg-neutral-700 dark:text-neutral-400'
  }
}
</script>

<template>
  <ScrollContainer wrapper-class="flex flex-col gap-y-4 max-sm:gap-y-2">
    <div class="grid grid-cols-1 gap-4 max-sm:gap-2 md:grid-cols-2 lg:grid-cols-4">
      <div
        v-for="(stat, index) in taskStats"
        :key="index"
        class="flex items-center justify-between gap-x-4 overflow-hidden rounded border border-naive-border bg-naive-card p-6 transition-[background-color,border-color]"
      >
        <div class="flex-1">
          <span class="text-sm font-medium text-neutral-450">{{ stat.title }}</span>
          <div class="mt-1 mb-1.5 flex gap-x-4 text-2xl text-neutral-700 dark:text-neutral-400">
            <NNumberAnimation
              :to="stat.value"
              :precision="0"
            />
          </div>
          <div class="text-xs text-neutral-500 dark:text-neutral-400">任务统计</div>
        </div>
        <div>
          <div
            class="grid place-items-center rounded-full p-3"
            :class="stat.iconBgClass"
          >
            <span
              class="size-7"
              :class="stat.iconClass"
            />
          </div>
        </div>
      </div>
    </div>

    <div class="grid grid-cols-1 gap-4 overflow-hidden max-sm:gap-2 lg:grid-cols-12">
      <div class="col-span-1 lg:col-span-5">
        <div class="grid grid-cols-1 gap-4 max-sm:gap-2">
          <div
            class="rounded border border-naive-border bg-naive-card px-5 pt-5 pb-4.5 transition-[background-color,border-color]"
            style="height: 300px"
          >
            <div
              ref="taskProgressChart"
              class="h-full"
            />
          </div>
          <div
            class="rounded border border-naive-border bg-naive-card p-5 transition-[background-color,border-color]"
          >
            <div class="mb-4 flex items-center justify-between">
              <h3 class="text-lg font-medium text-neutral-700 dark:text-neutral-400">近期事件</h3>
              <span class="text-sm text-neutral-450">查看全部</span>
            </div>
            <div class="space-y-3">
              <div
                v-for="event in upcomingEvents"
                :key="event.id"
                class="flex items-center gap-x-3 rounded p-3 transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-750"
              >
                <div class="flex-shrink-0">
                  <div
                    class="grid place-items-center rounded-full bg-blue-100 p-2 text-blue-600 dark:bg-blue-500/20 dark:text-blue-400"
                  >
                    <span class="iconify size-4 ph--calendar"></span>
                  </div>
                </div>
                <div class="flex-1">
                  <div class="text-sm font-medium text-neutral-600 dark:text-neutral-400">
                    {{ event.title }}
                  </div>
                  <div
                    class="mt-0.5 flex items-center text-xs text-neutral-500 dark:text-neutral-500"
                  >
                    <span class="mr-1 iconify size-3.5 ph--clock"></span>
                    {{ event.time }} - {{ event.location }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="col-span-1 lg:col-span-7">
        <div class="grid grid-cols-1 gap-4 max-sm:gap-2">
          <div
            class="rounded border border-naive-border bg-naive-card p-5 transition-[background-color,border-color]"
          >
            <div class="mb-4 flex items-center justify-between">
              <h3 class="text-lg font-medium text-neutral-700 dark:text-neutral-400">最近任务</h3>
              <span class="text-sm text-neutral-450">查看全部</span>
            </div>
            <div class="overflow-x-auto">
              <table class="w-full text-left">
                <thead class="border-b border-naive-border">
                  <tr>
                    <th class="px-4 py-3 text-sm font-medium text-neutral-450">任务名称</th>
                    <th class="px-4 py-3 text-sm font-medium text-neutral-450">状态</th>
                    <th class="px-4 py-3 text-sm font-medium text-neutral-450">优先级</th>
                    <th class="px-4 py-3 text-sm font-medium text-neutral-450">负责人</th>
                    <th class="px-4 py-3 text-sm font-medium text-neutral-450">截止日期</th>
                  </tr>
                </thead>
                <tbody>
                  <tr
                    v-for="task in recentTasks.slice(0, 6)"
                    :key="task.id"
                    class="border-b border-naive-border transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-750"
                  >
                    <td class="px-4 py-3 text-sm text-neutral-600 dark:text-neutral-400">
                      {{ task.title }}
                    </td>
                    <td class="px-4 py-3">
                      <span
                        class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium"
                        :class="getStatusBadgeClass(task.status)"
                      >
                        {{
                          {
                            pending: '待处理',
                            'in-progress': '进行中',
                            completed: '已完成',
                            overdue: '已逾期',
                          }[task.status]
                        }}
                      </span>
                    </td>
                    <td class="px-4 py-3">
                      <span
                        class="inline-flex items-center rounded-full px-2 py-1 text-xs font-medium"
                        :class="getPriorityBadgeClass(task.priority)"
                      >
                        {{
                          {
                            low: '低',
                            medium: '中',
                            high: '高',
                            urgent: '紧急',
                          }[task.priority]
                        }}
                      </span>
                    </td>
                    <td class="px-4 py-3 text-sm text-neutral-500 dark:text-neutral-500">
                      {{ task.assignee }}
                    </td>
                    <td class="px-4 py-3 text-sm text-neutral-500 dark:text-neutral-500">
                      {{ task.dueDate }}
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
          <div
            class="rounded border border-naive-border bg-naive-card p-5 transition-[background-color,border-color]"
          >
            <div class="mb-4 flex items-center justify-between">
              <h3 class="text-lg font-medium text-neutral-700 dark:text-neutral-400">活动动态</h3>
              <span class="text-sm text-neutral-450">刷新</span>
            </div>
            <div class="space-y-3">
              <div
                v-for="activity in activityFeed"
                :key="activity.id"
                class="flex items-start gap-x-3 rounded p-3 transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-750"
              >
                <div class="mt-0.5 flex-shrink-0">
                  <div
                    class="grid place-items-center rounded-full bg-gray-100 p-1.5 text-gray-600 dark:bg-neutral-700 dark:text-neutral-400"
                  >
                    <span class="iconify size-3.5 ph--activity"></span>
                  </div>
                </div>
                <div class="flex-1">
                  <div class="text-sm text-neutral-600 dark:text-neutral-400">
                    <span class="font-medium">{{ activity.user }}</span> {{ activity.activity }}
                  </div>
                  <div class="mt-0.5 text-xs text-neutral-500 dark:text-neutral-500">
                    {{ activity.time }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </ScrollContainer>
</template>
